Passed
Pull Request — master (#3805)
by
unknown
17:20
created

sha256.js ➔ str2rstr_utf8   B

Complexity

Conditions 8

Size

Total Lines 35
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 27
dl 0
loc 35
rs 7.3333
c 0
b 0
f 0
1
/*!
2
 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
3
 * in FIPS 180-1
4
 * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
5
 * in FIPS 180-2
6
 *
7
 * Version 2.2 Copyright Paul Johnston 2000 - 2009.
8
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
9
 *
10
 * Distributed under the BSD License
11
 * See http://pajhome.org.uk/crypt/md5 for details.
12
 * Also http://anmar.eu.org/projects/jssha2/
13
 */
14
15
/**
16
 * Configurable variables. You may need to tweak these to be compatible with
17
 * the server-side, but the defaults work in most cases.
18
 */
19
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase        */
20
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance   */
21
22
/**
23
 * These are the functions you'll want to call
24
 * They take string arguments and return hex encoded strings
25
 */
26
function hex_sha1(s) {return rstr2hex(rstr_sha1(str2rstr_utf8(s)));}
27
function hex_sha256(s) {return rstr2hex(rstr_sha256(str2rstr_utf8(s)));}
28
29
/**
30
 * Calculate the SHA1 of a raw string
31
 */
32
function rstr_sha1(s)
33
{
34
	return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
35
}
36
37
/**
38
 * Calculate the sha256 of a raw string
39
 */
40
function rstr_sha256(s)
41
{
42
	return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
43
}
44
45
/**
46
 * Encode a string as utf-8.
47
 * For efficiency, this assumes the input is valid utf-16.
48
 */
49
function str2rstr_utf8(input)
50
{
51
	var output = "";
52
	var i = -1;
53
	var x, y;
54
55
	while (++i < input.length)
56
	{
57
		/* Decode utf-16 surrogate pairs */
58
		x = input.charCodeAt(i);
59
		y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
60
		if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
61
		{
62
			x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
63
			i++;
64
		}
65
66
		/* Encode output as utf-8 */
67
		if (x <= 0x7F)
68
			output += String.fromCharCode(x);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
69
		else if (x <= 0x7FF)
70
			output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
71
					0x80 | (x & 0x3F));
72
		else if (x <= 0xFFFF)
73
			output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
74
					0x80 | ((x >>> 6) & 0x3F),
75
					0x80 | (x & 0x3F));
76
		else if (x <= 0x1FFFFF)
77
			output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
78
					0x80 | ((x >>> 12) & 0x3F),
79
					0x80 | ((x >>> 6) & 0x3F),
80
					0x80 | (x & 0x3F));
81
	}
82
	return output;
83
}
84
85
/**
86
 * Convert a raw string to an array of big-endian words
87
 * Characters >255 have their high-byte silently ignored.
88
 */
89
function rstr2binb(input)
90
{
91
	var output = Array(input.length >> 2);
92
	for (var i = 0; i < output.length; i++)
93
		output[i] = 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
94
	for (var i = 0; i < input.length * 8; i += 8)
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 92. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
95
		output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
96
	return output;
97
}
98
99
/**
100
 * Convert an array of big-endian words to a string
101
 */
102
function binb2rstr(input)
103
{
104
	var output = "";
105
	for (var i = 0; i < input.length * 32; i += 8)
106
		output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
107
	return output;
108
}
109
110
/**
111
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
112
 */
113
function binb_sha1(x, len)
114
{
115
	/* append padding */
116
	x[len >> 5] |= 0x80 << (24 - len % 32);
117
	x[((len + 64 >> 9) << 4) + 15] = len;
118
119
	var w = Array(80);
120
	var a = 1732584193;
121
	var b = -271733879;
122
	var c = -1732584194;
123
	var d = 271733878;
124
	var e = -1009589776;
125
126
	for (var i = 0; i < x.length; i += 16)
127
	{
128
		var olda = a;
129
		var oldb = b;
130
		var oldc = c;
131
		var oldd = d;
132
		var olde = e;
133
134
		for (var j = 0; j < 80; j++)
135
		{
136
			if (j < 16)
137
				w[j] = x[i + j];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
138
			else
139
				w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
140
			var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
141
					safe_add(safe_add(e, w[j]), sha1_kt(j)));
142
			e = d;
143
			d = c;
144
			c = bit_rol(b, 30);
145
			b = a;
146
			a = t;
147
		}
148
149
		a = safe_add(a, olda);
150
		b = safe_add(b, oldb);
151
		c = safe_add(c, oldc);
152
		d = safe_add(d, oldd);
153
		e = safe_add(e, olde);
154
	}
155
	return Array(a, b, c, d, e);
156
157
}
158
159
/**
160
 * Perform the appropriate triplet combination function for the current
161
 * iteration
162
 */
163
function sha1_ft(t, b, c, d)
164
{
165
	if (t < 20)
166
		return (b & c) | ((~b) & d);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
167
	if (t < 40)
168
		return b ^ c ^ d;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
169
	if (t < 60)
170
		return (b & c) | (b & d) | (c & d);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
171
	return b ^ c ^ d;
172
}
173
174
/**
175
 * Determine the appropriate additive constant for the current iteration
176
 */
177
function sha1_kt(t)
178
{
179
	return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
180
			(t < 60) ? -1894007588 : -899497514;
181
}
182
183
/**
184
 * Bitwise rotate a 32-bit number to the left.
185
 */
186
function bit_rol(num, cnt)
187
{
188
	return (num << cnt) | (num >>> (32 - cnt));
189
}
190
191
/**
192
 * Convert a raw string to a hex string
193
 */
194
function rstr2hex(input)
195
{
196
	try {
197
		hexcase
198
	} catch (e) {
0 ignored issues
show
introduced by
This code is unreachable and can thus be removed without consequences.
Loading history...
199
		hexcase = 0;
0 ignored issues
show
Bug introduced by
The variable hexcase seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.hexcase.
Loading history...
200
	}
201
	var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
202
	var output = "";
203
	var x;
204
	for (var i = 0; i < input.length; i++)
205
	{
206
		x = input.charCodeAt(i);
207
		output += hex_tab.charAt((x >>> 4) & 0x0F)
208
				+ hex_tab.charAt(x & 0x0F);
209
	}
210
	return output;
211
}
212
213
/**
214
 * Main sha256 function, with its support functions
215
 */
216
function sha256_S(X, n) {return (X >>> n) | (X << (32 - n));}
217
function sha256_R(X, n) {return (X >>> n);}
218
function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
219
function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
220
function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
221
function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
222
function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
223
function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
224
function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
225
function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
226
function sha256_Gamma0512(x) {return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
227
function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
228
229
var sha256_K = new Array
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
230
	(
231
		1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
232
		-1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
233
		1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
234
		264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
235
		-1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
236
		113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
237
		1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
238
		-1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
239
		430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
240
		1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
241
		-1866530822, -1538233109, -1090935817, -965641998
242
	);
243
244
function binb_sha256(m, l)
245
{
246
	var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534, 1359893119, -1694144372, 528734635, 1541459225);
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
247
	var W = new Array(64);
248
	var a, b, c, d, e, f, g, h;
249
	var i, j, T1, T2;
250
251
	/* append padding */
252
	m[l >> 5] |= 0x80 << (24 - l % 32);
253
	m[((l + 64 >> 9) << 4) + 15] = l;
254
255
	for (i = 0; i < m.length; i += 16)
256
	{
257
		a = HASH[0];
258
		b = HASH[1];
259
		c = HASH[2];
260
		d = HASH[3];
261
		e = HASH[4];
262
		f = HASH[5];
263
		g = HASH[6];
264
		h = HASH[7];
265
266
		for (j = 0; j < 64; j++)
267
		{
268
			if (j < 16)
269
				W[j] = m[j + i];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
270
			else
271
				W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
272
						sha256_Gamma0256(W[j - 15])), W[j - 16]);
273
274
			T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
275
					sha256_K[j]), W[j]);
276
			T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
277
			h = g;
278
			g = f;
279
			f = e;
280
			e = safe_add(d, T1);
281
			d = c;
282
			c = b;
283
			b = a;
284
			a = safe_add(T1, T2);
285
		}
286
287
		HASH[0] = safe_add(a, HASH[0]);
288
		HASH[1] = safe_add(b, HASH[1]);
289
		HASH[2] = safe_add(c, HASH[2]);
290
		HASH[3] = safe_add(d, HASH[3]);
291
		HASH[4] = safe_add(e, HASH[4]);
292
		HASH[5] = safe_add(f, HASH[5]);
293
		HASH[6] = safe_add(g, HASH[6]);
294
		HASH[7] = safe_add(h, HASH[7]);
295
	}
296
	return HASH;
297
}
298
299
/**
300
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
301
 * to work around bugs in some JS interpreters.
302
 */
303
function safe_add(x, y)
304
{
305
	var lsw = (x & 0xFFFF) + (y & 0xFFFF);
306
	var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
307
	return (msw << 16) | (lsw & 0xFFFF);
308
}